package mmi.gui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.geom.Point2D;
import java.io.File;
import java.sql.Timestamp;
import java.util.Vector;

import javax.swing.JColorChooser;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;

import mmi.event.ColourChangedEvent;
import mmi.event.ColourChangedEventListener;
import mmi.event.ObjectAddedEvent;
import mmi.event.ObjectAddedEventListener;
import mmi.event.ObjectMovedEvent;
import mmi.event.ObjectMovedEventListener;
import mmi.event.ObjectResizedEvent;
import mmi.event.ObjectResizedEventListener;
import mmi.event.ObjectRotatedEvent;
import mmi.event.ObjectRotatedEventListener;
import mmi.event.ShapeChangedEvent;
import mmi.event.ShapeChangedEventListener;
import mmi.event.TrialStartedEvent;
import mmi.event.TrialStartedEventListener;
import mmi.event.TrialStoppedEvent;
import mmi.event.TrialStoppedEventListener;
import mmi.file.ReadFile;
import mmi.file.WriteFile;
import mmi.gui.shape.Shape;
import mmi.gui.widget.DrawingBar;
import mmi.gui.widget.ExperimentBar;
import mmi.gui.widget.ExperimentFrame;
import mmi.gui.widget.LineWidthChooser;
import mmi.gui.widget.ProgramBar;
import mmi.gui.widget.QuestionnaireFrame;
import mmi.gui.widget.StatusBar;
import mmi.utils.Action;
import mmi.utils.Utils;

/**
 * The main frame of the application
 * 
 * @author louis
 *
 */
public class MainFrame extends JFrame implements ActionListener, ColourChangedEventListener, ShapeChangedEventListener,
ObjectMovedEventListener, ObjectRotatedEventListener, ObjectAddedEventListener, ObjectResizedEventListener
{
	private static final long serialVersionUID = 6318881844109457248L;

	ProgramBar toolbar = new ProgramBar(this);
	StatusBar statusBar = new StatusBar(this);
        DrawingArea drawingArea = new DrawingArea(this);
	DrawingBar drawingBar = new DrawingBar(this);
	ExperimentBar experimentBar = new ExperimentBar(this);



	public final ExperimentFrame experimentFrame = new ExperimentFrame();
	public final QuestionnaireFrame questionnaireFrame = new QuestionnaireFrame(this);

	private boolean trialRunning = false;

	private JMenuBar menuBar = null;

	private JMenu menuFile = null;
	private JMenuItem menuItemNew = null;
	private JMenuItem menuItemOpen = null;
	private JMenuItem menuItemSave = null;
	private JMenuItem menuItemSaveAs = null;
	private JMenuItem menuItemExit = null;

	private JMenu menuDraw = null;
	private JMenuItem menuItemDraw = null;
	private JMenuItem menuItemFill = null;
	private JMenuItem menuItemMove = null;
	private JMenuItem menuItemTop = null;
	private JMenuItem menuItemResize = null;
	private JMenuItem menuItemRotate = null;
	private JMenuItem menuItemDelete = null;

	private JMenu menuShape = null;
	private JMenuItem menuItemRectangle = null;
	private JMenuItem menuItemEllipse = null;
	private JMenuItem menuItemLine = null;
	private JMenuItem menuItemFreeLine = null;
	private JMenuItem menuItemTriangle = null;
	private JMenuItem menuItemText = null;

	private JMenu menuTools = null;
	private JMenuItem menuItemFillColourChooser = null;
	private JMenuItem menuItemLineColourChooser = null;
	private JMenuItem menuItemLineWidthChooser = null;
	private JMenuItem menuItemFontChooser = null;
	private JMenuItem menuItemReplayMode = null;

	private JMenu menuHelp = null;
	private JMenuItem menuItemEnableDebug = null;
	private JMenuItem menuItemAbout = null;

	Timestamp trialStart = null;

	Timestamp trialEnd = null;

	Timestamp trialEndPrev = null;

	Vector<Double> trialTimes = new Vector<Double>();

	/**
	 * Default constructor
	 */
	public MainFrame()
	{
		super();
		initialise();
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void colourChangedEventOccured(ColourChangedEvent evt) {
		//

	}

	public void cursorDragged(Point2D fromPoint, Point2D toPoint)
	{
		statusBar.getCs().setCoordinate(toPoint);
		statusBar.getWs().setWidth(new Point2D.Double(Math.abs(fromPoint.getX() - toPoint.getX()), Math.abs(fromPoint.getY() - toPoint.getY())));
	}

	public void cursorMoved(Point2D point)
	{
		statusBar.getCs().setCoordinate(point);
	}

	public void cursorReleased()
	{
		statusBar.getWs().setWidth(new Point2D.Double());
	}
	/**
	 * @return the drawingArea
	 */
	public DrawingArea getDrawingArea() {
		return drawingArea;
	}
        /**
	 * @return the drawingBar
	 */
	public DrawingBar getDrawingBar() {
		return drawingBar;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuBar getMainFrameMenuBar()
	{
		if(menuBar == null)
		{
			menuBar = new JMenuBar();
			menuBar.add(getMenuFile());
			menuBar.add(getMenuTools());
			menuBar.add(getMenuDraw());
			menuBar.add(getMenuShape());
			menuBar.add(getMenuHelp());
		}
		return menuBar;
	}
	/**
	 * 
	 * @return
	 */
	private JMenu getMenuDraw()
	{
		if(menuDraw == null)
		{
			menuDraw = new JMenu("Mode");
			menuDraw.setMnemonic(KeyEvent.VK_M);

			menuDraw.add(getMenuItemDraw());
			menuDraw.add(getMenuItemFill());
			menuDraw.add(getMenuItemTop());
			menuDraw.add(getMenuItemMove());
			menuDraw.add(getMenuItemResize());
			menuDraw.add(getMenuItemRotate());
			menuDraw.add(getMenuItemDelete());

		}
		return menuDraw;
	}
	/**
	 * 
	 * @return
	 */
	private JMenu getMenuFile()
	{
		if(menuFile == null)
		{
			menuFile = new JMenu("File");
			menuFile.setMnemonic(KeyEvent.VK_F);

			menuFile.add(getMenuItemNew());
			menuFile.add(getMenuItemOpen());
			menuFile.addSeparator();

			menuFile.add(getMenuItemSave());
			menuFile.add(getMenuItemSaveAs());
			menuFile.addSeparator();

			menuFile.add(getMenuItemExit());
		}
		return menuFile;
	}
	/**
	 * 
	 * @return
	 */
	private JMenu getMenuHelp()
	{
		if(menuHelp == null)
		{
			menuHelp = new JMenu("Help");
			menuHelp.setMnemonic(KeyEvent.VK_H);

			menuHelp.add(getMenuItemEnableDebug());
			menuHelp.add(getMenuItemAbout());
		}
		return menuHelp;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemAbout()
	{
		if(menuItemAbout == null)
		{
			menuItemAbout = new JMenuItem("About", KeyEvent.VK_A);
			menuItemAbout.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					handleAbout();
				}
			});
		}
		return menuItemAbout;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemDelete()
	{
		if(menuItemDelete == null)
		{
			menuItemDelete = new JMenuItem("Delete");
			menuItemDelete.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.setDelete();
				}
			});
		}
		return menuItemDelete;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemDraw()
	{
		if(menuItemDraw == null)
		{
			menuItemDraw = new JMenuItem("Draw");
			menuItemDraw.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.setDraw();
				}
			});
		}
		return menuItemDraw;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemEllipse()
	{
		if(menuItemEllipse == null)
		{
			menuItemEllipse = new JMenuItem("Ellipse");
			menuItemEllipse.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.setShape(Shape.Shapes.Ellipse);
					drawingArea.setDraw();
				}
			});
		}
		return menuItemEllipse;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemEnableDebug()
	{
		if(menuItemEnableDebug == null)
		{
			menuItemEnableDebug = new JMenuItem("Enable debug", KeyEvent.VK_E);
			setMenuItemEnableDebug();

			menuItemEnableDebug.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					Application.setOutputDebug(!Application.isOutputDebug());
					Application.Trace("Enabling/Disabling trace");
					setMenuItemEnableDebug();
					repaint();
				}
			});
		}
		return menuItemEnableDebug;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemExit()
	{
		if(menuItemExit == null)
		{
			menuItemExit = new JMenuItem("Exit", KeyEvent.VK_X);
			menuItemExit.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					handleExit();
				}
			});
		}
		return menuItemExit;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemFill()
	{
		if(menuItemFill == null)
		{
			menuItemFill = new JMenuItem("Fill");
			menuItemFill.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.setFill();
				}
			});
		}
		return menuItemFill;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemFillColourChooser()
	{
		if(menuItemFillColourChooser == null)
		{
			menuItemFillColourChooser = new JMenuItem("Choose fill colour");
			menuItemFillColourChooser.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.setFillColour(JColorChooser.showDialog(MainFrame.this, "Choose fill colour", Color.pink));
				}
			});
		}
		return menuItemFillColourChooser;
	}
	/**
	 * 
	 * @return
	 */
	@SuppressWarnings("unused")
	private JMenuItem getMenuItemFontChooser()
	{
		if(menuItemFontChooser == null)
		{
			menuItemFontChooser = new JMenuItem("Choose font");
			menuItemFontChooser.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.replay();
				}
			});
		}
		return menuItemFontChooser;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemFreeLine()
	{
		if(menuItemFreeLine == null)
		{
			menuItemFreeLine = new JMenuItem("Free Line");
			menuItemFreeLine.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.setShape(Shape.Shapes.FreeLine);
					drawingArea.setDraw();
				}
			});
		}
		return menuItemFreeLine;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemLine()
	{
		if(menuItemLine == null)
		{
			menuItemLine = new JMenuItem("Line");
			menuItemLine.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.setShape(Shape.Shapes.Line);
					drawingArea.setDraw();
				}
			});
		}
		return menuItemLine;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemLineColourChooser()
	{
		if(menuItemLineColourChooser == null)
		{
			menuItemLineColourChooser = new JMenuItem("Choose line colour");
			menuItemLineColourChooser.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.setLineColour(JColorChooser.showDialog(MainFrame.this, "Choose line colour", Color.pink));
				}
			});
		}
		return menuItemLineColourChooser;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemLineWidthChooser()
	{
		if(menuItemLineWidthChooser == null)
		{
			menuItemLineWidthChooser = new JMenuItem("Choose line width");
			menuItemLineWidthChooser.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					new LineWidthChooser(MainFrame.this);
				}
			});
		}
		return menuItemLineWidthChooser;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemMove()
	{
		if(menuItemMove == null)
		{
			menuItemMove = new JMenuItem("Move");
			menuItemMove.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.setMove();
				}
			});
		}
		return menuItemMove;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemNew()
	{
		if(menuItemNew == null)
		{
			menuItemNew = new JMenuItem("New", KeyEvent.VK_N);
			menuItemNew.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.reset();
				}
			});
		}
		return menuItemNew;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemOpen()
	{
		if(menuItemOpen == null)
		{
			menuItemOpen = new JMenuItem("Open File...", KeyEvent.VK_O);
			menuItemOpen.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					JFileChooser fileChooser = new JFileChooser();
					int rv = fileChooser.showOpenDialog(MainFrame.this);

					if (rv == JFileChooser.APPROVE_OPTION) {
						File file = fileChooser.getSelectedFile();
						ReadFile rf = new ReadFile(file);
						Application.Trace("Opening: " + file.getName() + "." + "\n");

						drawingArea.setActionList(rf.getActionList());
						drawingArea.printActionList();
					}

				}
			});
		}
		return menuItemOpen;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemRectangle()
	{
		if(menuItemRectangle == null)
		{
			menuItemRectangle = new JMenuItem("Rectangle");
			menuItemRectangle.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.setShape(Shape.Shapes.Rectangle);
					drawingArea.setDraw();
				}
			});
		}
		return menuItemRectangle;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemReplayMode()
	{
		if(menuItemReplayMode == null)
		{
			menuItemReplayMode = new JMenuItem("Enable replay", KeyEvent.VK_R);
			menuItemReplayMode.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.replay();
				}
			});
		}
		return menuItemReplayMode;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemResize()
	{
		if(menuItemResize == null)
		{
			menuItemResize = new JMenuItem("Resize");
			menuItemResize.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.setResize();
				}
			});
		}
		return menuItemResize;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemRotate()
	{
		if(menuItemRotate == null)
		{
			menuItemRotate = new JMenuItem("Rotate");
			menuItemRotate.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.setRotate();
				}
			});
		}
		return menuItemRotate;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemSave()
	{
		if(menuItemSave == null)
		{
			menuItemSave = new JMenuItem("Save", KeyEvent.VK_S);
			menuItemSave.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					JFileChooser fileChooser = new JFileChooser();
					int rv = fileChooser.showSaveDialog(MainFrame.this);

					if (rv == JFileChooser.APPROVE_OPTION) {
						File file = fileChooser.getSelectedFile();
						new WriteFile(file, drawingArea.getActionList(), questionnaireFrame.getAnswers());
						Application.Trace("Saving: " + file.getName() + "." + "\n");

					}
				}
			});
		}
		return menuItemSave;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemSaveAs()
	{
		if(menuItemSaveAs == null)
		{
			menuItemSaveAs = new JMenuItem("Save As...");
			menuItemSaveAs.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					//					JFileChooser fileChooser = new JFileChooser();
					//					int rv = fileChooser.showOpenDialog(MainFrame.this);
				}
			});
		}
		return menuItemSaveAs;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemText()
	{
		if(menuItemText == null)
		{
			menuItemText = new JMenuItem("Text");
			menuItemText.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.setText();
				}
			});
		}
		return menuItemText;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemTop()
	{
		if(menuItemTop == null)
		{
			menuItemTop = new JMenuItem("Top");
			menuItemTop.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.setTop();
				}
			});
		}
		return menuItemTop;
	}
	/**
	 * 
	 * @return
	 */
	private JMenuItem getMenuItemTriangle()
	{
		if(menuItemTriangle == null)
		{
			menuItemTriangle = new JMenuItem("Triangle");
			menuItemTriangle.addActionListener(new java.awt.event.ActionListener()
			{
				/*
				 * (non-Javadoc)
				 * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
				 */
				public void actionPerformed(java.awt.event.ActionEvent e)
				{
					drawingArea.setShape(Shape.Shapes.Triangle);
					drawingArea.setDraw();
				}
			});
		}
		return menuItemTriangle;
	}

	/**
	 * 
	 * @return
	 */
	private JMenu getMenuShape()
	{
		if(menuShape == null)
		{
			menuShape = new JMenu("Shape");
			menuShape.setMnemonic(KeyEvent.VK_S);

			menuShape.add(getMenuItemRectangle());
			menuShape.add(getMenuItemEllipse());
			menuShape.add(getMenuItemTriangle());
			menuShape.add(getMenuItemLine());
			menuShape.add(getMenuItemFreeLine());
			menuShape.add(getMenuItemText());
		}
		return menuShape;
	}

	/**
	 * 
	 * @return
	 */
	private JMenu getMenuTools()
	{
		if(menuTools == null)
		{
			menuTools = new JMenu("Tools");
			menuTools.setMnemonic(KeyEvent.VK_T);

			menuTools.add(getMenuItemLineColourChooser());
			menuTools.add(getMenuItemFillColourChooser());
			menuTools.add(getMenuItemLineWidthChooser());
			menuTools.addSeparator();
			menuTools.add(getMenuItemReplayMode());
		}
		return menuTools;
	}

	/**
	 * 
	 */
	private void handleAbout()
	{
		String iconAbout = "The icons used in this program are distributed under the GPL license\n" +
		"They belong to the GNOME icon set (http://www.gnome.org/). See the GNU\n" +
		"General Public License for more details:\n" +
		"http://www.gnu.org/copyleft/gpl.html\n";

		String authorAbout = "This program is written for the course Human Machine Interaction.\n" +
		"For more information, bugs and other remarks, feel free to mail me\n" +
		"at l.onrust@student.science.ru.nl\n";

		String finalAbout = iconAbout + "\n" + authorAbout;

		JOptionPane.showMessageDialog(this, finalAbout);
	}
	/**
	 * 
	 */
	private void handleExit()
	{
		dispose();
	}
	/**
	 * Initialises the frame. It sets the values needed and calls the functions needed
	 * to realise the frame
	 */
	private void initialise()
	{

		setSize(800, 500);
		setName("mainFrame");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setTitle("Drawing tool");

		setJMenuBar(getMainFrameMenuBar());

		this.setLayout(new BorderLayout());
		add(toolbar, BorderLayout.NORTH);
		add(experimentBar, BorderLayout.EAST);
		add(drawingBar, BorderLayout.WEST);
		add(drawingArea, BorderLayout.CENTER);
		add(statusBar, BorderLayout.SOUTH);

		drawingArea.addColourChangedEventListener(new ColourChangedEventListener() {

			@Override
			public void colourChangedEventOccured(ColourChangedEvent evt) {
				toolbar.getColourChooser().colourChangedEventOccured(evt);
			}
		});

		drawingArea.addObjectAddedEventListener(new ObjectAddedEventListener() {

			@Override
			public void objectAddedEventOccured(ObjectAddedEvent evt) {
				Vector<Double> t = new Vector<Double>();
				for(Action a : drawingArea.getActionAddList())
				{
					t.add(Utils.timestampDiff(a.getTimeEnd(), a.getTimeStart()));
				}
				experimentFrame.setDrawingTimes(t);

				if(trialStart == null)
				{
					for(Action a : drawingArea.getActionAddList())
					{
						if(trialEndPrev == null)
						{
							trialStart = drawingArea.getActionAddList().firstElement().getTimeStart();
							trialEndPrev = trialStart;
						} else
							if(Utils.timestampAfter(a.getTimeStart(), trialEndPrev))
							{
								trialStart = a.getTimeStart();
							}
					}
				}
				trialEnd = drawingArea.getActionAddList().lastElement().getTimeEnd();
			}
		});

		drawingArea.addObjectMovedEventListener(new ObjectMovedEventListener() {

			@Override
			public void objectMovedEventOccured(ObjectMovedEvent evt) {
				Vector<Double> t = new Vector<Double>();
				for(Action a : drawingArea.getActionMoveList())
				{
					t.add(Utils.timestampDiff(a.getTimeEnd(), a.getTimeStart()));
				}
				experimentFrame.setMovingTimes(t);

				if(trialStart == null)
				{
					for(Action a : drawingArea.getActionMoveList())
					{
						if(trialEndPrev == null)
						{
							trialStart = drawingArea.getActionMoveList().firstElement().getTimeStart();
							trialEndPrev = trialStart;
						} else
							if(Utils.timestampAfter(a.getTimeStart(), trialEndPrev))
							{
								trialStart = a.getTimeStart();
							}
					}

				}
				trialEnd = drawingArea.getActionMoveList().lastElement().getTimeEnd();
			}
		});

		drawingArea.addObjectResizedEventListener(new ObjectResizedEventListener() {

			@Override
			public void objectResizedEventOccured(ObjectResizedEvent evt) {
				Vector<Double> t = new Vector<Double>();
				for(Action a : drawingArea.getActionResizeList())
				{
					t.add(Utils.timestampDiff(a.getTimeEnd(), a.getTimeStart()));
				}
				experimentFrame.setResizingTimes(t);

				if(trialStart == null)
				{
					for(Action a : drawingArea.getActionMoveList())
					{
						if(trialEndPrev == null)
						{
							trialStart = drawingArea.getActionResizeList().firstElement().getTimeStart();
							trialEndPrev = trialStart;
						} else
							if(Utils.timestampAfter(a.getTimeStart(), trialEndPrev))
							{
								trialStart = a.getTimeStart();
							}
					}
				}
				trialEnd = drawingArea.getActionResizeList().lastElement().getTimeEnd();
			}
		});

		drawingArea.addObjectRotatedEventListener(new ObjectRotatedEventListener() {

			@Override
			public void objectRotatedEventOccured(ObjectRotatedEvent evt) {
				Vector<Double> t = new Vector<Double>();
				for(Action a : drawingArea.getActionRotateList())
				{
					t.add(Utils.timestampDiff(a.getTimeEnd(), a.getTimeStart()));
				}
				experimentFrame.setRotatingTimes(t);

				if(trialStart == null)
				{
					for(Action a : drawingArea.getActionMoveList())
					{
						if(trialEndPrev == null)
						{
							trialStart = drawingArea.getActionRotateList().firstElement().getTimeStart();
							trialEndPrev = trialStart;
						} else
							if(Utils.timestampAfter(a.getTimeStart(), trialEndPrev))
							{
								trialStart = a.getTimeStart();
							}
					}
				}
				trialEnd = drawingArea.getActionRotateList().lastElement().getTimeEnd();
			}
		});

		experimentBar.addTrialStartedEventListener(new TrialStartedEventListener() {

			@Override
			public void trialStartedEventOccured(TrialStartedEvent evt) {
				trialStart = null;
				trialEnd = null;
				trialRunning = true;
			}
		});

		experimentBar.addTrialStoppedEventListener(new TrialStoppedEventListener() {

			@Override
			public void trialStoppedEventOccured(TrialStoppedEvent evt) {
				if(trialRunning)
				{
					if(trialStart != null && trialEnd != null)
					{
						trialTimes.add(Utils.timestampDiff(trialStart, trialEnd));
						experimentFrame.addTrialTime(Utils.timestampDiff(trialStart, trialEnd));
						Application.Trace(Double.toString(Utils.timestampDiff(trialStart, trialEnd)));
						trialEndPrev = trialEnd;
					} else
					{
						trialTimes.add(0.0);
					}
				}
				trialRunning = false;
			}
		});
	}

	@Override
	public void objectAddedEventOccured(ObjectAddedEvent evt) {
		// TODO Auto-generated method stub

	}

	@Override
	public void objectMovedEventOccured(ObjectMovedEvent evt) {
		// TODO Auto-generated method stub

	}

	@Override
	public void objectResizedEventOccured(ObjectResizedEvent evt) {
		// TODO Auto-generated method stub

	}

	@Override
	public void objectRotatedEventOccured(ObjectRotatedEvent evt) {
		// TODO Auto-generated method stub

	}

	public void setMenuItemEnableDebug()
	{
		if(Application.isOutputDebug()) {
			menuItemEnableDebug.setText("Disable debug");
		} else {
			menuItemEnableDebug.setText("Enable debug");
		}
	}

	@Override
	public void shapeChangedEventOccured(ShapeChangedEvent evt) {
		// TODO Auto-generated method stub
	}
}
